package com.example.lxj.system.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.example.lxj.base.utils.RedisUtils;
import com.example.lxj.system.entity.*;
import com.example.lxj.system.mapper.SysMenuMapper;
import com.example.lxj.system.mapper.SysRoleMapper;
import com.example.lxj.system.mapper.SysUserRoleMapper;
import com.example.lxj.system.service.ISysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 菜单权限Service业务层处理
 */
@Service
public class SysMenuServiceImpl implements ISysMenuService {
    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    /**
     * 查询菜单权限
     *
     * @param menuId 菜单权限主键
     * @return 菜单权限
     */
    @Override
    public SysMenu selectSysMenuByMenuId(Long menuId) {
        return sysMenuMapper.selectSysMenuByMenuId(menuId);
    }

    /**
     * 查询菜单权限列表
     *
     * @return 菜单权限
     */
    @Override
    public List<SysMenu> selectSysMenuList() {
        List<SysMenu> sysMenus = sysMenuMapper.selectSysMenuTreeList();
        return this.buildMenu(sysMenus);
    }

    /**
     * 新增菜单权限
     *
     * @param sysMenu 菜单权限
     * @return 结果
     */
    @Override
    public int insertSysMenu(SysMenu sysMenu) {
        sysMenu.setCreateTime(DateUtil.date());
        return sysMenuMapper.insertSysMenu(sysMenu);
    }

    /**
     * 修改菜单权限
     *
     * @param sysMenu 菜单权限
     * @return 结果
     */
    @Override
    public int updateSysMenu(SysMenu sysMenu) {
        sysMenu.setUpdateTime(DateUtil.date());
        return sysMenuMapper.updateSysMenu(sysMenu);
    }

    /**
     * 批量删除菜单权限
     *
     * @param menuIds 需要删除的菜单权限主键
     * @return 结果
     */
    @Override
    public int deleteSysMenuByMenuIds(Long[] menuIds) {
        return sysMenuMapper.deleteSysMenuByMenuIds(menuIds);
    }

    /**
     * 删除菜单权限信息
     *
     * @param menuId 菜单权限主键
     * @return 结果
     */
    @Override
    public int deleteSysMenuByMenuId(Long menuId) {
        return sysMenuMapper.deleteSysMenuByMenuId(menuId);
    }

    /**
     * 根据用户id获取
     *
     * @param userId 用户ID
     * @return
     */
    @Override
    public Map<String, Object> getMenuListByUserId(Long userId) {
        Map<String, Object> resultMap = new HashMap<>();
        List<SysMenu> sysMenus = null;
        List<String> perms = new ArrayList<>();
        // 判断是否为admin
        SysUserRole sysUserRole = sysUserRoleMapper.selectSysUserRoleByUserId(userId);
        if (1 == sysUserRole.getRoleId()) {
            sysMenus = sysMenuMapper.selectMenuTreeAll();
            perms.add("*:*");
        } else {
            sysMenus = sysMenuMapper.selectMenuTreeByUserId(userId);
            perms = sysMenus.stream().filter(sysMenu -> ObjectUtil.isNotEmpty(sysMenu.getPerms())).map(SysMenu::getPerms).collect(Collectors.toList());
        }
        List<SysMenu> menutreeData = this.buildMenu(sysMenus);
        List<RouterData> routerData = this.buildRouterData(sysMenus);
        resultMap.put("permission", perms);
        resultMap.put("routerData", routerData);
        resultMap.put("menutreeData", menutreeData);
        // 将权限存入redis
        redisUtils.del(userId.toString());
        redisUtils.set(userId.toString(), perms, 0);
        return resultMap;
    }

    @Override
    public List<Long> selectMenuListByRoleId(Long roleId) {
        SysRole sysRole = sysRoleMapper.selectSysRoleByRoleId(roleId);
        return sysMenuMapper.selectMenuListByRoleId(roleId, sysRole.isMenuCheckStrictly());
    }

    public List<RouterData> buildRouterData(List<SysMenu> menus) {
        List<RouterData> rootRouterData = new ArrayList<>();
        for (SysMenu menu : menus) {
            RouterData routerData = new RouterData();
            if (ObjectUtil.isNotEmpty(menu.getComponent())) {
                MetaData metaData = new MetaData();
                routerData.setPath("/" + menu.getPath());
                routerData.setName(menu.getPath());
                routerData.setComponent(menu.getComponent());
                metaData.setTitle(menu.getMenuName());
                routerData.setIcon(menu.getIcon());
                routerData.setMeta(metaData);
                rootRouterData.add(routerData);
            }
        }
        return rootRouterData;
    }

    public List<SysMenu> buildMenu(List<SysMenu> menus) {
        HashMap<Long, SysMenu> menuMap = new HashMap<>();
        List<SysMenu> rootMenus = new ArrayList<>();
        // 先将所有菜单放入map中
        for (SysMenu menu : menus){
            menuMap.put(menu.getMenuId(),menu);
        }
        for (SysMenu menu : menus) {
            if (ObjectUtil.isNull(menu.getParentId()) || menu.getParentId().equals(0L)) {
                rootMenus.add(menu);
            } else {
                SysMenu parent = menuMap.get(menu.getParentId());
                if (ObjectUtil.isNotNull(parent)) {
                    if (ObjectUtil.isNull(parent.getChildren())) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(menu);
                }
            }
        }
        return rootMenus;
    }
}
